#include "mediaplaylist.h"
#include <QRandomGenerator>
#include <QDebug>

MediaPlaylist::MediaPlaylist(QObject *parent) : QObject(parent) {}

int MediaPlaylist::currentIndex() const
{
    return m_currentIndex;
}

QUrl MediaPlaylist::currentMedia() const
{
    if (m_currentIndex >= 0 && m_currentIndex < m_mediaList.size()) {
        return m_mediaList.at(m_currentIndex);
    }
    return QUrl();
}

int MediaPlaylist::nextIndex(int steps) const
{
    if (m_mediaList.isEmpty()) {
        return -1;
    }

    switch (m_playbackMode) {
    case CurrentItemOnce:
    case CurrentItemInLoop:
        return m_currentIndex;
    case Sequential:
        return (m_currentIndex + steps) % m_mediaList.size();
    case Loop:
        return (m_currentIndex + steps) % m_mediaList.size();
    case Random:
        return randomIndex();
    }
    return -1;
}

int MediaPlaylist::previousIndex(int steps) const
{
    if (m_mediaList.isEmpty()) {
        return -1;
    }

    switch (m_playbackMode) {
    case CurrentItemOnce:
    case CurrentItemInLoop:
        return m_currentIndex;
    case Sequential:
    case Loop: {
        int index = m_currentIndex - steps;
        while (index < 0) {
            index += m_mediaList.size();
        }
        return index;
    }
    case Random:
        return randomIndex();
    }
    return -1;
}

void MediaPlaylist::addMedia(const QUrl &content)
{
    insertMedia(m_mediaList.size(), content);
}

void MediaPlaylist::addMedia(const QList<QUrl> &items)
{
    insertMedia(m_mediaList.size(), items);
}

void MediaPlaylist::insertMedia(int index, const QUrl &content)
{
    insertMedia(index, QList<QUrl>() << content);
}

void MediaPlaylist::insertMedia(int index, const QList<QUrl> &items)
{
    if (items.isEmpty()) {
        return;
    }

    int start = qBound(0, index, m_mediaList.size());
    int end = start + items.size() - 1;

    emit mediaAboutToBeInserted(start, end);
    for (int i = 0; i < items.size(); ++i) {
        m_mediaList.insert(start + i, items.at(i));
    }
    emit mediaInserted(start, end);

    if (m_currentIndex >= start) {
        m_currentIndex += items.size();
    }

    if (m_mediaList.size() == items.size()) {
        setCurrentIndex(0);
    }
}

bool MediaPlaylist::removeMedia(int pos)
{
    return removeMedia(pos, pos);
}

bool MediaPlaylist::removeMedia(int start, int end)
{
    if (start < 0 || end >= m_mediaList.size() || start > end) {
        return false;
    }

    emit mediaAboutToBeRemoved(start, end);
    for (int i = end; i >= start; --i) {
        m_mediaList.removeAt(i);
    }
    emit mediaRemoved(start, end);

    if (m_currentIndex >= start && m_currentIndex <= end) {
        if (m_mediaList.isEmpty()) {
            setCurrentIndex(-1);
        } else {
            setCurrentIndex(qMin(start, m_mediaList.size() - 1));
        }
    } else if (m_currentIndex > end) {
        m_currentIndex -= (end - start + 1);
    }

    return true;
}

void MediaPlaylist::clear()
{
    if (m_mediaList.isEmpty()) {
        return;
    }

    removeMedia(0, m_mediaList.size() - 1);
}

bool MediaPlaylist::isEmpty() const
{
    return m_mediaList.isEmpty();
}

int MediaPlaylist::mediaCount() const
{
    return m_mediaList.size();
}

QUrl MediaPlaylist::media(int index) const
{
    if (index >= 0 && index < m_mediaList.size()) {
        return m_mediaList.at(index);
    }
    return QUrl();
}

MediaPlaylist::PlaybackMode MediaPlaylist::playbackMode() const
{
    return m_playbackMode;
}

void MediaPlaylist::setPlaybackMode(PlaybackMode mode)
{
    if (m_playbackMode != mode) {
        m_playbackMode = mode;
        emit playbackModeChanged(mode);
    }
}

void MediaPlaylist::shuffle()
{
    if (m_mediaList.size() < 2) {
        return;
    }

    QList<QUrl> shuffled;

    while (!m_mediaList.isEmpty()) {
        int index = QRandomGenerator::global()->bounded(m_mediaList.size());
        shuffled.append(m_mediaList.takeAt(index));
    }

    m_mediaList = shuffled;
    m_currentIndex = m_mediaList.indexOf(currentMedia());
    emit mediaChanged(0, m_mediaList.size() - 1);
}

void MediaPlaylist::setCurrentIndex(int index)
{
    if (index == m_currentIndex) {
        return;
    }

    if (index >= m_mediaList.size()) {
        index = -1;
    }

    int oldIndex = m_currentIndex;
    m_currentIndex = index;

    if (oldIndex != m_currentIndex) {
        emit currentIndexChanged(m_currentIndex);
        emit currentMediaChanged(currentMedia());
        updatePlayerSource();
    }
}

void MediaPlaylist::next()
{
    if (m_mediaList.isEmpty()) {
        qDebug() << "Media list is empty";
        return;
    }
    setCurrentIndex(nextIndex());
    if (m_boundPlayer) {
        m_boundPlayer->play();
    }
}

void MediaPlaylist::previous()
{
    if (m_mediaList.isEmpty()) {
        qDebug() << "Media list is empty";
        return;
    }
    setCurrentIndex(previousIndex());
    if (m_boundPlayer) {
        m_boundPlayer->play();
    }
}

void MediaPlaylist::connectToPlayer(QMediaPlayer *player)
{
    bindToPlayer(player);

    if (m_player) {
        disconnect(m_player, &QMediaPlayer::playbackStateChanged,
                   this, &MediaPlaylist::handlePlayerStateChanged);
    }

    m_player = player;

    if (m_player) {
        connect(m_player, &QMediaPlayer::playbackStateChanged,
                this, &MediaPlaylist::handlePlayerStateChanged);
    }
}

void MediaPlaylist::handlePlayerStateChanged(QMediaPlayer::PlaybackState state)
{
    if (!m_boundPlayer) {
        return;
    }

    // 处理播放错误情况
    if (state == QMediaPlayer::StoppedState &&
        m_boundPlayer->error() != QMediaPlayer::NoError) {
        qWarning() << "Playback error:" << m_boundPlayer->errorString();
        m_boundPlayer->pause(); // 暂停播放器以防止错误状态持续
        return;
    }

    // 仅在播放停止且不是用户主动停止时处理
    if (state == QMediaPlayer::StoppedState &&
        m_boundPlayer->mediaStatus() == QMediaPlayer::EndOfMedia) {

        if (m_mediaList.isEmpty()) {
            m_boundPlayer->pause(); // 如果播放列表为空，则暂停播放器
            return;
        }

        switch (m_playbackMode) {
        case CurrentItemOnce:
            // 单曲播放一次，不自动继续
            break;

        case CurrentItemInLoop:
            // 单曲循环
            m_boundPlayer->setPosition(0);
            if (m_autoPlayNext) {
                m_boundPlayer->play();
            }
            break;

        case Sequential:
        case Loop:
            // 顺序播放或列表循环
            if (m_autoPlayNext) {
                next();
            }
            break;

        case Random:
            // 随机播放
            if (m_autoPlayNext) {
                setCurrentIndex(randomIndex());
            }
            break;
        }
    }
}

int MediaPlaylist::randomIndex() const
{
    if (m_mediaList.isEmpty()) {
        return -1;
    }
    if (m_mediaList.size() == 1) {
        return 0;
    }

    int index;
    do {
        index = QRandomGenerator::global()->bounded(m_mediaList.size());
    } while (index == m_currentIndex && m_mediaList.size() > 1);

    return index;
}

void MediaPlaylist::updatePlayerSource()
{
    if (!m_boundPlayer || m_currentIndex < 0 || m_currentIndex >= m_mediaList.size()) {
        return;
    }

    m_boundPlayer->setSource(m_mediaList.at(m_currentIndex));
}

void MediaPlaylist::bindToPlayer(QMediaPlayer *player)
{
    if (m_boundPlayer == player) {
        return;
    }

    unbindPlayer(); // 先解绑现有的

    if (player) {
        m_boundPlayer = player;

        // 连接播放器状态信号
        connect(player, &QMediaPlayer::playbackStateChanged,
                this, &MediaPlaylist::handlePlayerStateChanged);

        // 连接媒体状态信号（用于检测播放结束）
        connect(player, &QMediaPlayer::mediaStatusChanged,
                this, [this](QMediaPlayer::MediaStatus status) {
                    if (status == QMediaPlayer::EndOfMedia) {
                        this->handleMediaFinished();
                    }
                });

        // 连接错误信号
        connect(player, &QMediaPlayer::errorOccurred,
                this, [this]() {
                    qWarning() << "Player error:" << m_boundPlayer->errorString();
                });

        // 自动设置第一个媒体并播放（如果列表不为空）
        if (!m_mediaList.isEmpty() && m_currentIndex < 0) {
            setCurrentIndex(0);
        }

        // 如果已经有当前选中的媒体，更新播放器源
        if (m_currentIndex >= 0 && m_currentIndex < m_mediaList.size()) {
            updatePlayerSource();

            // 如果设置了自动播放且播放器当前是停止状态，则开始播放
            if (m_autoPlayOnBind && m_boundPlayer->playbackState() == QMediaPlayer::StoppedState) {
                m_boundPlayer->play();
            }
        }
    }
}

void MediaPlaylist::unbindPlayer()
{
    if (m_boundPlayer) {
        disconnect(m_boundPlayer, nullptr, this, nullptr);
        m_boundPlayer = nullptr;
    }
}

bool MediaPlaylist::isBoundToPlayer() const
{
    return m_boundPlayer != nullptr;
}

void MediaPlaylist::handleMediaFinished()
{
    if (!m_boundPlayer) return;

    switch (m_playbackMode) {
    case CurrentItemInLoop:
        m_boundPlayer->setPosition(0);
        m_boundPlayer->play();
        break;
    case CurrentItemOnce:
        // 不做任何操作，保持停止状态
        break;
    default:
        // 其他模式自动播放下一个
        next();
        break;
    }
}
